home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_9.zip
/
INTB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-27
|
47KB
|
1,857 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
/* Continuation of ada interpreter - auxiliary procedures */
/* Include standard header modules */
#include <stdlib.h>
#include <setjmp.h>
#include "config.h"
#include "int.h"
#include "ivars.h"
#include "machinep.h"
#include "farithp.h"
#include "taskingp.h"
#include "predefp.h"
#include "intcp.h"
#include "intbp.h"
extern jmp_buf raise_env;
static void update_address(int *);
static void image_attribute();
static void value_attribute();
static int same_dimensions(int *, int *);
static int compare_fields_record(int *, int *, int *);
void main_attr(int attribute, int dim) /*;attribute*/
{
switch(attribute) {
case ATTR_ADDRESS:
POP_ADDR(bse, off);
create(2, &bas1, &off1, &ptr1);/* ADDRESS is a record */
*ADDR(bas1, off1) = bse;
*ADDR(bas1, off1 + 1) = off;
PUSH_ADDR(bas1, off1);
break;
case ATTR_CALLABLE:
POP(value); /* task object */
value = (is_callable(value));
PUSH(value);
break;
case ATTR_COUNT:
POP(val2); /* member in family */
POP(val1); /* entry family */
value = count(val1, val2);
PUSH(value);
break;
case ATTR_T_CONSTRAINED:
break;
case ATTR_O_CONSTRAINED:
break;
case ATTR_T_FIRST:
case ATTR_T_LAST:
POP_ADDR(bse, off);/* type */
ptr = ADDR(bse, off);
size = SIZE(ptr);
if (TYPE(ptr) == TT_FX_RANGE) {
if (attribute == ATTR_T_FIRST)
PUSHL(FX_RANGE(ptr)->fxlow);
else
PUSHL(FX_RANGE(ptr)->fxhigh);
}
else if (TYPE(ptr) == TT_FL_RANGE) {
if (attribute == ATTR_T_FIRST)
PUSHF(FL_RANGE(ptr)->fllow);
else
PUSHF(FL_RANGE(ptr)->flhigh);
}
else if ((TYPE(ptr) == TT_I_RANGE)
|| (TYPE(ptr) == TT_E_RANGE)
|| (TYPE(ptr) == TT_ENUM)) {
if (attribute == ATTR_T_FIRST)
PUSH(I_RANGE(ptr)->ilow);
else
PUSH(I_RANGE(ptr)->ihigh);
}
#ifdef LONG_INT
else if (TYPE(ptr) == TT_L_RANGE) {
if (attribute == ATTR_T_FIRST)
PUSHL(L_RANGE(ptr)->llow);
else
PUSHL(L_RANGE(ptr)->lhigh);
}
#endif
else /* error */
raise(SYSTEM_ERROR,"Unknown type for attribute FIRST or LAST");
break;
case ATTR_O_FIRST:
case ATTR_O_LAST:
POP_ADDR(bse, off);/* type */
ptr = ADDR(bse, off);
POP_ADDR(bas1, off1);/* to get rid of array */
val1 = *ptr; /* type of type */
if (val1 == TT_S_ARRAY) {
if (attribute == ATTR_O_LAST)
value = S_ARRAY(ptr)->sahigh;
else
value = S_ARRAY(ptr)->salow;
PUSH(value);
}
else if (val1 == TT_C_ARRAY || val1 == TT_U_ARRAY) {
/* Beware: indices in reverse order */
ptr += 2 * (ARRAY(ptr)->dim - dim);
bse = ARRAY(ptr)->index1_base;
off = ARRAY(ptr)->index1_offset;
ptr = ADDR(bse, off);
if ((TYPE(ptr) == TT_I_RANGE)
||(TYPE(ptr) == TT_E_RANGE)
||(TYPE(ptr) == TT_ENUM)) {
if (attribute == ATTR_O_LAST)
PUSH(I_RANGE(ptr)->ihigh);
else
PUSH(I_RANGE(ptr)->ilow);
}
#ifdef LONG_INT
else if (TYPE(ptr) == TT_L_RANGE) {
if (attribute == ATTR_O_LAST)
PUSHL(L_RANGE(ptr)->lhigh);
else
PUSHL(L_RANGE(ptr)->llow);
}
#endif
}
else if (val1 == TT_D_ARRAY) {
bas1 = D_TYPE(ptr)->dbase;
off1 = D_TYPE(ptr)->doff;
ptr += WORDS_D_TYPE + 4 *(dim - 1);
if (attribute == ATTR_O_LAST)
ptr += 2;
if (*ptr == 0)
PUSH(*(ptr + 1));
else
raise(SYSTEM_ERROR, "Attribute on discriminant bound");
}
break;
case ATTR_T_LENGTH:
POP_ADDR(bse, off);
ptr = ADDR(bse, off);
size = SIZE(ptr);
if (size == 1) {
if (I_RANGE(ptr)->ihigh < I_RANGE(ptr)->ilow)
value = 0;
else
value = I_RANGE(ptr)->ihigh - I_RANGE(ptr)->ilow + 1;
PUSH(value);
}
#ifdef LONG_INT
else /* size=2 */ {
if (L_RANGE(ptr)->lhigh < L_RANGE(ptr)->llow)
lvalue = 0;
else
lvalue = L_RANGE(ptr)->lhigh - L_RANGE(ptr)->llow;
PUSHL(lvalue);
}
#endif
break;
case ATTR_O_LENGTH:
POP_ADDR(bse, off);/* type */
ptr = ADDR(bse, off);
POP_ADDR(bas1, off1);/* to get rid of array */
val1 = TYPE(ptr); /* type of type */
if (val1 == TT_S_ARRAY) {
/* the calculation of max is unuseful ! the substraction may
* produce an overflow and a positive result
*/
if (S_ARRAY(ptr)->sahigh < S_ARRAY(ptr)->salow)
value = 0;
else {
/*value=MAX(S_ARRAY(ptr)->sahigh-S_ARRAY(ptr)->salow + 1, 0);*/
value = S_ARRAY(ptr)->sahigh - S_ARRAY(ptr)->salow + 1;
}
PUSH(value);
}
else if (val1 == TT_C_ARRAY) {
/* Beware: indices in reverse order */
ptr += 2 * (ARRAY(ptr)->dim - dim);
bse = ARRAY(ptr)->index1_base;
off = ARRAY(ptr)->index1_offset;
ptr = ADDR(bse, off);
/* value = MAX(I_RANGE(ptr)->ihigh - I_RANGE(ptr)->ilow + 1, 0); */
if (I_RANGE(ptr)->ihigh < I_RANGE(ptr)->ilow)
value = 0;
else
value = I_RANGE(ptr)->ihigh - I_RANGE(ptr)->ilow + 1;
PUSH(value);
}
break;
case ATTR_T_RANGE:
POP_ADDR(bse, off);
ptr = ADDR(bse, off);
size = SIZE(ptr);
if (size == 1) {
PUSH(I_RANGE(ptr)->ilow);
PUSH(I_RANGE(ptr)->ihigh);
}
#ifdef LONG_INT
else /* size == 2 */ {
lvalue = L_RANGE(ptr)->lhigh - L_RANGE(ptr)->llow;
PUSHL(lvalue);
}
#endif
break;
case ATTR_O_RANGE:
POP_ADDR(bse, off);/* type */
ptr = ADDR(bse, off);
POP_ADDR(bas1, off1);/* to get rid of array */
val1 = TYPE(ptr); /* type of type */
if (val1 == TT_S_ARRAY) {
val_high = S_ARRAY(ptr)->sahigh;
val_low = S_ARRAY(ptr)->salow;
PUSH(val_low);
PUSH(val_high);
}
else if (val1 == TT_C_ARRAY) {
/* Beware: indices in reverse order */
ptr += 2 * (ARRAY(ptr)->dim - dim);
bse = ARRAY(ptr)->index1_base;
off = ARRAY(ptr)->index1_offset;
ptr = ADDR(bse, off);
size = SIZE(ptr);
if (size == 1) {
PUSH(I_RANGE(ptr)->ilow);
PUSH(I_RANGE(ptr)->ihigh);
}
#ifdef LONG_INT
else /*(size == 2)*/ {
PUSHL(L_RANGE(ptr)->llow);
PUSHL(L_RANGE(ptr)->lhigh);
}
#endif
}
break;
case ATTR_IMAGE:
image_attribute();
break;
case ATTR_VALUE:
value_attribute();
break;
case ATTR_PRED:
POP_ADDR(bse, off);/* type */
ptr = ADDR(bse, off);
if ((TYPE(ptr) == TT_I_RANGE)
||(TYPE(ptr) == TT_E_RANGE)
||(TYPE(ptr) == TT_ENUM)) {
POP(value);
if (value <= I_RANGE(ptr)->ilow)
raise(CONSTRAINT_ERROR, "Out of range (PRED)");
value--;
PUSH(value);
}
#ifdef LONG_INT
else if (TYPE(ptr) == TT_L_RANGE) {
POPL(lvalue);
if (lvalue <= L_RANGE(ptr)->llow)
raise (CONSTRAINT_ERROR, "Out of range (PRED)");
lvalue--;
PUSHL(lvalue);
}
#endif
else /* error */
raise(SYSTEM_ERROR,"Unknown type for attribute PRED");
break;
case ATTR_SUCC:
POP_ADDR(bse, off);/* type */
ptr = ADDR(bse, off);
if ((TYPE(ptr) == TT_I_RANGE)
||(TYPE(ptr) == TT_E_RANGE)
||(TYPE(ptr) == TT_ENUM)) {
POP(value);
if (value >= I_RANGE(ptr)->ihigh)
raise(CONSTRAINT_ERROR, "Out of range (SUCC)");
value++;
PUSH(value);
}
#ifdef LONG_INT
else if (TYPE(ptr) == TT_L_RANGE) {
POPL(lvalue);
if (lvalue >= L_RANGE(ptr)->lhigh)
raise (CONSTRAINT_ERROR, "Out of range (SUCC)");
lvalue++;
PUSHL(lvalue);
}
#endif
else /* error */
raise(SYSTEM_ERROR,"Unknown type for attribute SUCC");
break;
case ATTR_SIZE:
POP_ADDR(bse, off);
ptr1 = ADDR(bse, off);
value = SIZE(ptr1);
if ((TYPE(ptr1) == TT_RECORD
|| TYPE(ptr1) == TT_C_RECORD
|| TYPE(ptr1) == TT_U_RECORD
|| TYPE(ptr1) == TT_V_RECORD)
&& (U_RECORD(ptr1)->repr_size != 0)) {
PUSH(U_RECORD(ptr1)->repr_size);
}
else if (TYPE(ptr1) == TT_ACCESS) {
PUSH(32);
}
else {
PUSH(value * BITS_SU);
}
break;
case ATTR_STORAGE_SIZE:
POP_ADDR(bse, off);
ptr1 = ADDR(bse, off);
if (TYPE(ptr1) == TT_ACCESS) {